package com.getword.utils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.util.*;

public class POIUtils {

    // 根据类型的严格性，自己讲字符串转成相应的格式
    public static List<List<String>> readExcel(InputStream in, String ext) throws Exception {
        if (ext.endsWith("xls")) {
            return readXls(in);
        } else if (ext.endsWith("xlsx")) {
            return readXlsx(in);
        } else {
            return null;
        }
    }

    public static List<List<String>> readXlsx(InputStream in) throws Exception {
        XSSFWorkbook workbook = new XSSFWorkbook(in);

        List<List<String>> result = new ArrayList<List<String>>();
        // 循环每一页，并处理当前循环页
        for (XSSFSheet xssfSheet : workbook) {
            if (xssfSheet == null) {
                continue;
            }
            // 处理当前页，循环读取每一行
            for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
                XSSFRow xssfRow = xssfSheet.getRow(rowNum);
                int minColIx = xssfRow.getFirstCellNum();
                int maxColIx = xssfRow.getLastCellNum();
                List<String> rowList = new ArrayList<String>();
                for (int colIx = minColIx; colIx < maxColIx; colIx++) {
                    XSSFCell cell = xssfRow.getCell(colIx);
                    if (cell == null) {
                        continue;
                    }
                    rowList.add(getStringVal(cell));
                }
                result.add(rowList);
            }
        }
        return result;
    }

    // 只读取第一个sheet
    public static List<List<String>> readXls(InputStream in) throws Exception {
        HSSFWorkbook workbook = new HSSFWorkbook(in);

        List<List<String>> result = new ArrayList<List<String>>();
        // 循环每一页，并处理当前循环页
        HSSFSheet sheet = workbook.getSheetAt(0);
        if (sheet == null) {
            return null;
        }
        // 处理当前页，循环读取每一行
        for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
            HSSFRow xssfRow = sheet.getRow(rowNum);
            int minColIx = xssfRow.getFirstCellNum();
            int maxColIx = xssfRow.getLastCellNum();
            List<String> rowList = new ArrayList<String>();
            for (int colIx = minColIx; colIx < maxColIx; colIx++) {
                HSSFCell cell = xssfRow.getCell(colIx);
                if (cell == null) {
                    continue;
                }
                rowList.add(getStringVal(cell));
            }
            result.add(rowList);
        }
        return result;
    }

    // xls
    public static String getStringVal(HSSFCell cell) {
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_BOOLEAN:
                return cell.getBooleanCellValue() ? "TRUE" : "FALSE";
            case Cell.CELL_TYPE_FORMULA:
                return cell.getCellFormula();
            case Cell.CELL_TYPE_NUMERIC:
                cell.setCellType(Cell.CELL_TYPE_STRING);
                return cell.getStringCellValue();
            case Cell.CELL_TYPE_STRING:
                return cell.getStringCellValue();
            default:
                return "";
        }
    }

    public static String getStringVal(XSSFCell cell) {
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_BOOLEAN:
                return cell.getBooleanCellValue() ? "TRUE" : "FALSE";
            case Cell.CELL_TYPE_FORMULA:
                return cell.getCellFormula();
            case Cell.CELL_TYPE_NUMERIC:
                cell.setCellType(Cell.CELL_TYPE_STRING);
                return cell.getStringCellValue();
            case Cell.CELL_TYPE_STRING:
                return cell.getStringCellValue();
            default:
                return "";
        }
    }

    // 将数据转成json，List<Map>,适用于大纲,深度为3
    public static List<Map<String, Object>> renderJson(InputStream in, String ext) {
        List<Map<String, Object>> content = new ArrayList<>();

        List<List<String>> lists = null;
        try {
            lists = POIUtils.readExcel(in, ext);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (lists == null) {
            return null;
        }
        // 逐层插入

        List<Map<String, String>> data = new ArrayList<>();

        for (List<String> list : lists) {
            data.add(new HashMap<String, String>() {{
                put("num", list.get(0));
                put("name", list.get(1));
                put("intro", list.size() >= 3 ? list.get(2) : "");
            }});
        }
        // 寻找一级标题，并删除
        for (Map<String, String> line : data) {
            String num = line.get("num");
            int length = StringUtils.split(num, "_").length;
            if (length == 1) {
//                System.out.println(line);
                // 一级大纲直接加入到content中
                Map<String, Object> map = new HashMap<>();
                map.put("num", num);
                map.put("name", line.get("name"));
                map.put("intro", line.get("intro"));
                content.add(map);
            }
        }

        // 寻找2级标题，并删除
        for (Map<String, String> line : data) {
            String num = line.get("num");
            int length = StringUtils.split(num, "_").length;
            if (length == 2) {
                int i = Integer.parseInt(StringUtils.split(num, "_")[0]);
//                System.out.println(line);
                // 将该行加入到第i个一级标题中
                List<Map<String, Object>> children = (List<Map<String, Object>>) content.get(i - 1).get("children");
                if (children == null) {
                    children = new ArrayList<>();
                    content.get(i - 1).put("children", children);
                }
                // 2级大纲直接加入到content中的元素的children的元素中
                Map<String, Object> map = new HashMap<>();
                map.put("num", num);
                map.put("name", line.get("name"));
                map.put("intro", line.get("intro"));
                children.add(map);
            }
        }
        // 寻找3级标题，并删除
        for (Map<String, String> line : data) {
            String num = line.get("num");
            int length = StringUtils.split(num, "_").length;

            if (length == 3) {
                int l1 = Integer.parseInt(StringUtils.split(num, "_")[0]);  // 一级
                int l2 = Integer.parseInt(StringUtils.split(num, "_")[1]);  // 二级
//                System.out.println(line);
                List<Map<String, Object>> chapter = (List<Map<String, Object>>) content.get(l1 - 1).get("children");
                List<Map<String, Object>> children = (List<Map<String, Object>>) chapter.get(l2 - 1).get("children");
                if (children == null) {
                    children = new ArrayList<>();
                    chapter.get(l2 - 1).put("children", children);
                }
                // 3级大纲直接加入到content中的元素的children的元素中
                Map<String, Object> map = new HashMap<>();
                map.put("num", num);
                map.put("name", line.get("name"));
                map.put("intro", line.get("intro"));
                children.add(map);
            }
        }
        return content;
    }

    // 将数据转成json，List<Map>,适用于大纲,深度为3

    /**
     * [
     * {id:1,xxx,pid:-1}
     * {id:2,xx, pid:-1}
     * {id:3,xxx, pid:1}
     * ]
     * 节点id++
     *
     * @param in
     * @param ext
     * @return
     */
    public static List<Map<String, Object>> renderList(InputStream in, String ext) {
        List<Map<String, Object>> content = new ArrayList<>();

        List<List<String>> lists = null;
        try {
            lists = POIUtils.readExcel(in, ext);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (lists == null) {
            return null;
        }
        // 逐层插入

        List<Map<String, String>> data = new ArrayList<>();

        for (List<String> list : lists) {
            data.add(new HashMap<String, String>() {{
                put("num", list.get(0));
                put("name", list.get(1));
                put("intro", list.size() >= 3 ? list.get(2) : "");
            }});
        }
        // 寻找一级标题，并删除
        for (Map<String, String> line : data) {
            String num = line.get("num");
            int length = StringUtils.split(num, "_").length;
            if (length == 1) {
                int id = content.size() + 1;
//                System.out.println(line);
                // 一级大纲直接加入到content中
                Map<String, Object> map = new HashMap<>();
                map.put("id", id);
                map.put("num", num);
                map.put("name", line.get("name"));
                map.put("intro", line.get("intro"));
                map.put("pid", -1);
                content.add(map);
            }
        }

        // 寻找2级标题，并删除
        for (Map<String, String> line : data) {
            String num = line.get("num");
            String[] num_str = StringUtils.split(num, "_");
            int length = num_str.length;
            if (length == 2) {
                int id = content.size() + 1;
                // 上一层num=num_str[0]
                int pid = search(content, num_str[0]);
                ;
                // 2级大纲直接加入到content中的元素的children的元素中
                Map<String, Object> map = new HashMap<>();
                map.put("id", id);
                map.put("num", num);
                map.put("name", line.get("name"));
                map.put("intro", line.get("intro"));
                map.put("pid", pid);
                content.add(map);
            }
        }
        // 寻找3级标题，并删除
        for (Map<String, String> line : data) {
            String num = line.get("num");
            String[] num_str = StringUtils.split(num, "_");
            int length = num_str.length;

            if (length == 3) {
                int id = content.size() + 1;
                // 上一层num=num_str[0]
                int pid = search(content, num_str[0] + "_" + num_str[1]);
                ;
                // 3级大纲直接加入到content中的元素的chil""dren的元素中
                Map<String, Object> map = new HashMap<>();
                map.put("id", id);
                map.put("num", num);
                map.put("name", line.get("name"));
                map.put("intro", line.get("intro"));
                map.put("pid", pid);
                content.add(map);
            }
        }
        return content;
    }

    //
    private static int search(List<Map<String, Object>> content, String num) {
        for (Map<String, Object> c : content) {
            if (num.equals(c.get("num"))) {
                return (int) c.get("id");
            }
        }
        return -1;
    }

    /**
     * 写入Excel
     * in: [{},{}] list
     * out:file
     */
    public static InputStream writeOutline(List<Map<String, Object>> content, String path) {
        path += ".xlsx";
        //创建excel工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        //创建工作表sheet
        XSSFSheet sheet = workbook.createSheet();
        HSSFCell cell = null;
        //写入数据
        Row row = sheet.createRow(0);
        row.createCell(0).setCellValue("num");
        row.createCell(1).setCellValue("title");
        row.createCell(2).setCellValue("intro");
        // 将content排序, 'num'
        Collections.sort(content, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                return compareList(o1.get("num").toString(), o2.get("num").toString());
            }
        });
        int i = 1;
        for(Map<String, Object> map : content){
            row = sheet.createRow(i);
            row.createCell(0).setCellValue(map.get("num").toString());
            row.createCell(1).setCellValue(map.get("name").toString());
            row.createCell(2).setCellValue(map.get("intro").toString());
            i++;
        }


        //创建excel文件
        File file = new File(path);
        try {
            file.createNewFile();
            //将excel写入
            FileOutputStream stream = FileUtils.openOutputStream(file);
            workbook.write(stream);
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 读取
        InputStream is = null;
        try {
            is = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return is;
    }

    // 2_1<3  2<3 2<2_1
    private static int compareList(String s1, String s2) {
        String[] s1_list = s1.split("_");
        String[] s2_list = s2.split("_");
        int len1 = s1_list.length;
        int len2 = s2_list.length;
        for (int i = 0; i < Math.min(len1, len2); i++) {
            int a = Integer.parseInt(s1_list[i]);
            int b = Integer.parseInt(s2_list[i]);
            if (a == b) {
                continue;
            } else {
                return a > b ? 1 : -1;
            }
        }
        return len1 > len2 ? 1 : -1; // 2>2_1
    }

    public static void main(String[] args) {
        String[] a = {"1","2","3","2_1","2_2","2_3","2_1_1","2_1_2","2_2_1"};
        List<String> s = Arrays.asList(a);
        Collections.sort(s, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return compareList(o1, o2);
            }
        });
        System.out.println(s);
    }
}
